package com.thread.chapter2;

import cn.hutool.core.thread.ThreadUtil;
import lombok.Data;

@Data
public class Demo2211 extends Thread {

    private String execMethod = new String();
    private Demo2211 task;

    public Demo2211(Demo2211 task, String execMethod) {
        this.task = task;
        this.execMethod = execMethod;
    }

    public synchronized void syncMethodA() {
        System.out.println("syncMethodA 开始:" + currentThread().getName());
        ThreadUtil.sleep(20000);
        System.out.println("syncMethodA 结束:" + currentThread().getName());
    }

    public synchronized void syncMethodB() {
        System.out.println("syncMethodB 开始:" + currentThread().getName());
        System.out.println("syncMethodB 结束:" + currentThread().getName());
    }

    public void syncMethodC() {
        synchronized (new Object()) {
            System.out.println("syncMethodC 开始:" + currentThread().getName());
            ThreadUtil.sleep(40000);
            System.out.println("syncMethodC 结束:" + currentThread().getName());
        }
    }

    public void syncMethodD() {
        synchronized (new Object()) {
            System.out.println("syncMethodD 开始:" + currentThread().getName());
            System.out.println("syncMethodD 结束:" + currentThread().getName());
        }
    }

    @Override
    public void run() {
        super.run();
        if ("A".equals(execMethod)) {
            task.syncMethodA();
        } else if ("B".equals(execMethod)) {
            task.syncMethodB();
        } else if ("C".equals(execMethod)) {
            task.syncMethodC();
        } else if ("D".equals(execMethod)) {
            task.syncMethodD();
        }
    }

    public static void main(String[] args) {

        //同一个对象的两个同步方法用的是对象锁,那么就有可能会出现等待,B要等A执行完才执行
        Demo2211 task = new Demo2211();
        Demo2211 a = new Demo2211(task, "A");
        a.start();
        Demo2211 b = new Demo2211(task, "B");
        b.start();

        //上面情况可以用同步块解决,对象锁不是同一个,因此C和D可以同时执行
        Demo2211 c = new Demo2211(task, "C");
        c.start();
        Demo2211 d = new Demo2211(task, "D");
        d.start();
    }
}
